package com.google.code.mochaccino.framework.crypto.scheme.impl;

/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.google.code.mochaccino.framework.crypto.EncryptionException;
import com.google.code.mochaccino.framework.crypto.cipher.CipherHandler;
import com.google.code.mochaccino.framework.crypto.scheme.EncryptionSchemeBase;
import java.security.GeneralSecurityException;
import java.security.Key;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;

/**
 * Symmetric Encryption Scheme
 *
 *
 */
public class EncryptionSchemeSymmetric extends EncryptionSchemeBase {

	/** The Key */
	private Key key;

	/**
	 * Constructor
	 *
	 * @param rawKey    The Raw Key in bytes
	 * @param algorithm The Algorithm
	 * @param handler   The Handler
	 */
	public EncryptionSchemeSymmetric( byte[] rawKey, String algorithm, CipherHandler handler ) throws EncryptionException {
		this( rawKey, algorithm, null, handler );
	}

	/**
	 * Constructor
	 *
	 * @param rawKey    The Raw Key
	 * @param algorithm The Algorithm
	 * @param provider  The Provider
	 * @param handler   The Handler
	 */
	public EncryptionSchemeSymmetric( byte[] rawKey, String algorithm, String provider, CipherHandler handler ) throws EncryptionException {
		super( algorithm, provider, handler );
		try {
			SecretKeyFactory keyFactory = null;
			if ( getProvider() != null ) {
				keyFactory = SecretKeyFactory.getInstance( getAlgorithm(), getProvider() );
			} else {
				keyFactory = SecretKeyFactory.getInstance( getAlgorithm() );
			}
			key = keyFactory.generateSecret( new SecretKeySpec( rawKey, getAlgorithm() ) );
		} catch ( GeneralSecurityException e ) {
			throw new EncryptionException( e );
		}
	}

	@Override
	protected Key getPrivateKey() {
		return key;
	}

	@Override
	protected Key getPublicKey() {
		return key;
	}

	/** Generate the Key with specified algo and provider */
	public static final byte[] generateKey( String algo, String provider ) throws EncryptionException {
		try {
			KeyGenerator gen = KeyGenerator.getInstance( algo, provider );
			SecretKey skey = gen.generateKey();
			return skey.getEncoded();
		} catch ( GeneralSecurityException e ) {
			throw new EncryptionException( e );
		}
	}
}
